package juc.scenarios.startup;

import lombok.Getter;

import java.util.*;
import java.util.concurrent.*;

/**
 * 简化的服务启动检查演示
 * <p>
 * 不依赖Spring框架，直接演示CountDownLatch的使用
 */
public class SimpleStartupDemo {

    @Getter
    public enum ServiceState {
        HEALTHY("✅"),
        UNHEALTHY("❌"),
        TIMEOUT("⏰"),
        ERROR("💥");

        private final String emoji;

        ServiceState(String emoji) {
            this.emoji = emoji;
        }

    }

    // 服务检查结果
    @Getter
    static class ServiceCheckResult {
        private final String serviceName;
        private final ServiceState state;
        private final long duration;
        private final String message;

        public ServiceCheckResult(String serviceName, ServiceState state, long duration, String message) {
            this.serviceName = serviceName;
            this.state = state;
            this.duration = duration;
            this.message = message;
        }

    }

    // 服务接口
    interface HealthCheckService {
        String getServiceName();

        ServiceCheckResult checkHealth() throws InterruptedException;
    }

    // 数据库服务检查
    static class DatabaseHealthCheckService implements HealthCheckService {
        @Override
        public String getServiceName() {
            return "数据库服务";
        }

        @Override
        public ServiceCheckResult checkHealth() throws InterruptedException {
            long startTime = System.currentTimeMillis();

            try {
                // 模拟数据库连接检查
                Thread.sleep(800 + new Random().nextInt(400));

                long duration = System.currentTimeMillis() - startTime;

                // 90%概率成功
                if (new Random().nextDouble() < 0.9) {
                    return new ServiceCheckResult(getServiceName(), ServiceState.HEALTHY, duration, "数据库连接正常");
                } else {
                    return new ServiceCheckResult(getServiceName(), ServiceState.UNHEALTHY, duration, "数据库连接失败");
                }
            } catch (Exception e) {
                long duration = System.currentTimeMillis() - startTime;
                return new ServiceCheckResult(getServiceName(), ServiceState.ERROR, duration, "检查异常: " + e.getMessage());
            }
        }
    }

    // 缓存服务检查
    static class CacheHealthCheckService implements HealthCheckService {
        @Override
        public String getServiceName() {
            return "缓存服务";
        }

        @Override
        public ServiceCheckResult checkHealth() throws InterruptedException {
            long startTime = System.currentTimeMillis();

            try {
                // 模拟缓存服务检查
                Thread.sleep(600 + new Random().nextInt(300));

                long duration = System.currentTimeMillis() - startTime;

                // 95%概率成功
                if (new Random().nextDouble() < 0.95) {
                    return new ServiceCheckResult(getServiceName(), ServiceState.HEALTHY, duration, "缓存服务正常");
                } else {
                    return new ServiceCheckResult(getServiceName(), ServiceState.UNHEALTHY, duration, "缓存服务异常");
                }
            } catch (Exception e) {
                long duration = System.currentTimeMillis() - startTime;
                return new ServiceCheckResult(getServiceName(), ServiceState.ERROR, duration, "检查异常: " + e.getMessage());
            }
        }
    }

    // 消息队列服务检查
    static class MessageQueueHealthCheckService implements HealthCheckService {
        @Override
        public String getServiceName() {
            return "消息队列服务";
        }

        @Override
        public ServiceCheckResult checkHealth() throws InterruptedException {
            long startTime = System.currentTimeMillis();

            try {
                // 模拟消息队列检查
                Thread.sleep(1000 + new Random().nextInt(500));

                long duration = System.currentTimeMillis() - startTime;

                // 85%概率成功
                if (new Random().nextDouble() < 0.85) {
                    return new ServiceCheckResult(getServiceName(), ServiceState.HEALTHY, duration, "消息队列服务正常");
                } else {
                    return new ServiceCheckResult(getServiceName(), ServiceState.UNHEALTHY, duration, "消息队列服务异常");
                }
            } catch (Exception e) {
                long duration = System.currentTimeMillis() - startTime;
                return new ServiceCheckResult(getServiceName(), ServiceState.ERROR, duration, "检查异常: " + e.getMessage());
            }
        }
    }

    // 配置中心服务检查
    static class ConfigCenterHealthCheckService implements HealthCheckService {
        @Override
        public String getServiceName() {
            return "配置中心服务";
        }

        @Override
        public ServiceCheckResult checkHealth() throws InterruptedException {
            long startTime = System.currentTimeMillis();

            try {
                // 模拟配置中心检查
                Thread.sleep(400 + new Random().nextInt(200));

                long duration = System.currentTimeMillis() - startTime;

                // 98%概率成功
                if (new Random().nextDouble() < 0.98) {
                    return new ServiceCheckResult(getServiceName(), ServiceState.HEALTHY, duration, "配置中心服务正常");
                } else {
                    return new ServiceCheckResult(getServiceName(), ServiceState.UNHEALTHY, duration, "配置中心服务异常");
                }
            } catch (Exception e) {
                long duration = System.currentTimeMillis() - startTime;
                return new ServiceCheckResult(getServiceName(), ServiceState.ERROR, duration, "检查异常: " + e.getMessage());
            }
        }
    }

    // 启动检查管理器
    static class StartupCheckManager {
        private final List<HealthCheckService> services;
        private final ExecutorService executor;

        public StartupCheckManager(List<HealthCheckService> services) {
            this.services = services;
            this.executor = Executors.newFixedThreadPool(services.size());
        }

        public Map<String, ServiceCheckResult> performStartupChecks(long timeoutMillis)
                throws InterruptedException, TimeoutException {

            System.out.println("开始执行服务启动检查...");
            System.out.println("检查的服务数量: " + services.size());
            System.out.println("服务列表: " + services.stream()
                    .map(HealthCheckService::getServiceName)
                    .toList());

            long startTime = System.currentTimeMillis();
            CountDownLatch latch = new CountDownLatch(services.size());
            Map<String, ServiceCheckResult> results = new ConcurrentHashMap<>();

            // 提交所有检查任务
            for (HealthCheckService service : services) {
                executor.submit(() -> {
                    try {
                        ServiceCheckResult result = service.checkHealth();
                        results.put(service.getServiceName(), result);
                        System.out.println("✓ " + service.getServiceName() + " 检查完成: " +
                                result.getState().getEmoji() + " " + result.getMessage());
                    } catch (Exception e) {
                        long duration = System.currentTimeMillis() - startTime;
                        ServiceCheckResult errorResult = new ServiceCheckResult(
                                service.getServiceName(), ServiceState.ERROR, duration, "检查异常: " + e.getMessage());
                        results.put(service.getServiceName(), errorResult);
                        System.out.println("✗ " + service.getServiceName() + " 检查异常: " + e.getMessage());
                    } finally {
                        latch.countDown();
                    }
                });
            }

            // 等待所有检查完成或超时
            boolean completed = latch.await(timeoutMillis, TimeUnit.MILLISECONDS);

            if (!completed) {
                throw new TimeoutException("服务检查超时");
            }

            long totalDuration = System.currentTimeMillis() - startTime;
            System.out.println("\n所有服务检查完成，总耗时: " + totalDuration + "ms");

            return results;
        }

        public void shutdown() {
            executor.shutdown();
        }
    }

    public static void main(String[] args) {
        System.out.println("=== 简化的服务启动检查演示 ===");
        System.out.println("演示CountDownLatch在多服务并发检查中的应用\n");

        // 创建服务检查列表
        List<HealthCheckService> services = Arrays.asList(
                new DatabaseHealthCheckService(),
                new CacheHealthCheckService(),
                new MessageQueueHealthCheckService(),
                new ConfigCenterHealthCheckService()
        );

        // 创建检查管理器
        StartupCheckManager checkManager = new StartupCheckManager(services);

        try {
            long startTime = System.currentTimeMillis();

            // 执行检查（10秒超时）
            Map<String, ServiceCheckResult> results = checkManager.performStartupChecks(10000L);

            long endTime = System.currentTimeMillis();
            long totalDuration = endTime - startTime;

            // 输出结果汇总
            System.out.println("\n=== 检查结果汇总 ===");
            System.out.println("检查ID: " + UUID.randomUUID());
            System.out.println("总耗时: " + totalDuration + "ms");
            System.out.println("总服务数: " + services.size());

            long healthyCount = results.values().stream()
                    .filter(r -> r.getState() == ServiceState.HEALTHY)
                    .count();
            long unhealthyCount = results.values().stream()
                    .filter(r -> r.getState() != ServiceState.HEALTHY)
                    .count();

            System.out.println("健康服务数: " + healthyCount);
            System.out.println("异常服务数: " + unhealthyCount);
            System.out.println("是否全部健康: " + (unhealthyCount == 0 ? "是" : "否"));

            System.out.println("\n=== 详细状态 ===");
            results.forEach((serviceName, result) -> {
                System.out.println("服务: " + serviceName);
                System.out.println("  状态: " + result.getState().getEmoji() + " " + result.getState());
                System.out.println("  耗时: " + result.getDuration() + "ms");
                System.out.println("  消息: " + result.getMessage());
                System.out.println();
            });

            // 性能分析
            if (unhealthyCount == 0) {
                System.out.println("🎉 所有服务检查通过，系统可以正常启动！");
            } else {
                System.out.println("⚠️  有服务异常，系统启动失败！");
            }

            // 性能对比
            System.out.println("\n=== 性能分析 ===");
            long estimatedSerialTime = results.values().stream()
                    .mapToLong(ServiceCheckResult::getDuration)
                    .sum();
            System.out.println("串行检查预估时间: " + estimatedSerialTime + "ms");
            System.out.println("并行检查实际时间: " + totalDuration + "ms");
            System.out.println("节省时间: " + (estimatedSerialTime - totalDuration) + "ms");
            System.out.println("效率提升: " + String.format("%.1f%%",
                    (double) (estimatedSerialTime - totalDuration) / estimatedSerialTime * 100));

        } catch (TimeoutException e) {
            System.err.println("检查超时: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("检查过程中发生异常: " + e.getMessage());
            e.printStackTrace();
        } finally {
            checkManager.shutdown();
        }

        System.out.println("\n=== 演示完成 ===");

        // CountDownLatch 学习要点
        System.out.println("\n📚 本次演示中CountDownLatch的作用：");
        System.out.println("1. 🎯 协调多个服务并发检查");
        System.out.println("2. ⏱️  等待所有检查完成后统一汇总结果");
        System.out.println("3. 🔒 确保结果收集的线程安全性");
        System.out.println("4. ⚡ 大幅提升检查效率（并行 vs 串行）");
        System.out.println("5. 🛡️ 支持超时机制，避免永久等待");
        System.out.println("\n💡 关键实现：");
        System.out.println("- 使用CountDownLatch(services.size())初始化计数器");
        System.out.println("- 每个服务检查完成后调用latch.countDown()");
        System.out.println("- 主线程调用latch.await(timeout, TimeUnit.MILLISECONDS)等待结果");
        System.out.println("- 使用ConcurrentHashMap确保线程安全的并发结果收集");
    }
}